package br.ufmg.vod.collections;

import java.util.Arrays;
import java.util.LinkedList;

import junit.framework.TestCase;

public class IntQueueStackTest extends TestCase {
	
	private static final double STOP_PROBABILITY = 0.001;
	final static int PARTIAL = 128;
	final static int NUM = 5096*PARTIAL;

	public void testQueue(){

		IntQueue stack = new IntQueueStack(NUM);
		LinkedList<Integer> expected = new LinkedList<Integer>();
		while(Math.random() > STOP_PROBABILITY && stack.size() < NUM ){
			int toInsert = (int) (Math.random()*PARTIAL);
			toInsert = Math.min(toInsert, NUM-stack.size());
			this.enqueueRandom(toInsert, stack, expected);
			int toRemove = (int) (Math.random()*stack.size());
			assertDequeue(toRemove, stack, expected);
		}
		assertDequeue(stack.size(), stack, expected);
		assertTrue(stack.isEmpty()&&expected.isEmpty());
	}


	public void testStack(){
		IntStack stack = new IntQueueStack(NUM);
		LinkedList<Integer> expected = new LinkedList<Integer>();
		while(Math.random() > 0.1 && stack.size() < NUM ){
			int toInsert = (int) (Math.random()*PARTIAL);
			toInsert = Math.min(toInsert, NUM-stack.size());
			this.pushRandom(toInsert, stack, expected);
			int toRemove = (int) (Math.random()*stack.size());
			assertPop(toRemove, stack, expected);
		}
		assertPop(stack.size(), stack, expected);
		assertTrue(stack.isEmpty()&&expected.isEmpty());
	}
	
	
	
	private void assertDequeue(int numToDequeue, IntQueue queue, LinkedList<Integer> queue2) {
		for (int j = 0; j < numToDequeue; j++) {
			assertEquals((int)queue2.removeFirst(), queue.dequeue());
		}
	}


	private void enqueueRandom(int NUM, IntQueue queue,
			LinkedList<Integer> queue2) {
		for (int i = 0; i < NUM; i++) {
			int num = (int) (Math.random()*Integer.MAX_VALUE);
			queue.enqueue(num);
			queue2.addLast(num);
		}
	}
	
	private void assertPop(int numToDequeue, IntStack queue, LinkedList<Integer> queue2) {
		for (int j = 0; j < numToDequeue; j++) {
			assertEquals((int)queue2.removeLast(), queue.pop());
		}
	}


	private void pushRandom(int NUM, IntStack queue,
			LinkedList<Integer> queue2) {
		for (int i = 0; i < NUM; i++) {
			int num = (int) (Math.random()*Integer.MAX_VALUE);
			queue.push(num);
			queue2.addLast(num);
		}
	}
	
	
}
